今天來介紹一個比較小的議題——Stack Output。
當我們創建完資源後,會希望輸出資源有關的屬性方便取用。例如建立了 Application Load Balancer 後,希望可以輸出 Load Balnacer 的 DNS name,讓我們可以連線。或是輸出 VpcId、SubnetId 等資訊,讓其他的 Project 可以參考這些值。
而在未來我們介紹到使用多個 Project 的時候,就會需要參考到其他 Project 的 Stack Output。
例如所有 VPC、Subnet 的設定都在 project-infra
中,接著我們有另一個 project-app1
會建立 EC2 Instance。開立 EC2 機器的時候,就會需要指定 VPC、Subnet。如果 project-infra
有將 VPC ID、Subnet ID 透過 Stack Output 輸出的話,我們就可以參考 project-infra
的輸出資料。也就不需要將 VPC ID 放置於其他地方儲存,或是寫死在程式裡面了。
如何參考其他 Project 的 Stack Output 容我留到之後的文章介紹。這邊先介紹如何匯出資料。
在 TypeScript 中,要將資料輸出的方式很簡單,假設我們的專案都是寫在 Top Level(就是沒有特別包裝一個非同步匿名函式 (async anonymous function) ),直接使用 TypeScript 的 export 語法即可輸出了。
例如以下範例即可將 vpcId 做為 Stack Output 輸出
import * as pulumi from '@pulumi/pulumi';
import * as aws from '@pulumi/aws';
// 建立 VPC
const vpc = new aws.ec2.Vpc('my-vpc', {
cidrBlock: '10.120.0.0/16'
});
// 將 vpc 的 id 屬性賦值到 vpcId 變數,並將 vpcId 做為 Stack Output
export const vpcId = vpc.id;
那如果是有非同步匿名函式的狀況下,可以直接將要輸出的資料以 Object 的方式回傳。
例如以下範例:
import * as pulumi from '@pulumi/pulumi';
import * as aws from '@pulumi/aws';
export = async () => {
// 建立 VPC
const vpc = new aws.ec2.Vpc('my-vpc', {
cidrBlock: '10.120.0.0/16'
});
// 回傳一個 Object,在 TS/JS 中,我們常將 Object 當做 HashMap 使用。
return {
// Stack Output 中有一個 vpcId,值為 vpc 的 id 屬性
vpcId: vpc.id,
};
}
至於其他語言中,要輸出資料的話,就得透過 pulumi.export
函式來達成。
例如 python 中要輸出 VpcId 得這樣做:
import pulumi
import pulumi_aws as aws
// 建立 VPC
my_vpc = aws.ec2.Vpc('my-vpc',cidr_block="10.120.0.0")
// 輸出一個 Stack Output,叫做 vpc_id,內容為 my_vpc 的 id 屬性
pulumi.export('vpc_id', my_vpc.id)
每個語言要怎麼使用 Stack Output 請參考官方文件
接著來練習將之前建立的 VPC、Public Subnet、Private Subnet 資訊輸出。直接在函式最下方將我們想輸出的資料回傳即可。
return {
vpcId: myVpc.id,
publicSubnetIds: Object.values(publicSubnets).map(subnet => subnet.id),
privateSubnetIds: Object.values(privateSubnets).map(subnet => subnet.id),
igw: igw.id,
natGateway: natGateway.id,
};
接著執行 pulumi up
完成後,就可以在 console 輸出中看到我們的 Output 數值了。
Outputs:
igw : "igw-057395905a9300651"
natGateway : "nat-0525a2df0549f9d87"
privateSubnetIds: [
[0]: "subnet-07c0347881878ea7a"
[1]: "subnet-0859c9586bc678f88"
]
publicSubnetIds : [
[0]: "subnet-0bd6c6dd4501e6d6d"
[1]: "subnet-051b8eb71461c53d1"
]
vpcId : "vpc-02c2b3898482aede5"
這些輸出也可以在 Pulumi 的 Dashboard 中看到:
有些資源的輸出資料是屬於機敏資訊的,例如資料庫密碼,IAM User 的 AKSK 等資料。這些資訊 Pulumi 會自動將其加密,如果要查看,需要透過特殊的 CLI 指令才能解密。
那如果有些資訊本身不是機敏資訊,但我們想讓他成為機敏資訊輸出怎麼辦呢?
可以透過 pulumi.secret
函式將輸出的資訊標註為機敏資訊,例如以下範例,就會將 igw 的輸出標註為機敏資訊:
export const igw = pulumi.secret(igw.id)
在 console 的輸出也會顯示 [secret]
Outputs:
igw : [secret]
反之,如果原本是被 Pulumi 標註為機敏資訊的資料,可以透過 pulumi.unsecret
的函式將他反標註為一般資訊。
要查看 stack 的 output,可以透過 2 個指令完成。第一個為 pulumi stack
指令列出 Stack 所有的資訊,其中就會包含 Stack Output 的內容。
$ pulumi stack
Current stack is dev:
Owner: xxxxxx
Last updated: 1 day ago (2023-09-24 22:02:34.897349 +0800 CST)
Pulumi version used: v3.79.0
Current stack resources (20):
TYPE NAME
pulumi:pulumi:Stack aws-vpc-ts-dev
├─ aws:ec2/vpc:Vpc my-vpc
├─ aws:ec2/eip:Eip my-nat-gateway-eip
├─ aws:ec2/internetGateway:InternetGateway my-igw
├─ aws:ec2/subnet:Subnet my-private-subnet-ap-east-1a
├─ aws:ec2/subnet:Subnet my-public-subnet-2
├─ aws:ec2/defaultRouteTable:DefaultRouteTable my-default-rt
├─ aws:ec2/routeTable:RouteTable my-private-subnet-ap-east-1b-rt
├─ aws:ec2/subnet:Subnet my-public-subnet-1
├─ aws:ec2/subnet:Subnet my-private-subnet-ap-east-1b
├─ aws:ec2/routeTable:RouteTable my-private-subnet-ap-east-1a-rt
├─ aws:ec2/route:Route my-default-rt-default-route
├─ aws:ec2/routeTableAssociation:RouteTableAssociation my-public-subnet-2-rt-association
├─ aws:ec2/natGateway:NatGateway my-nat-gateway
├─ aws:ec2/routeTableAssociation:RouteTableAssociation my-public-subnet-1-rt-association
├─ aws:ec2/routeTableAssociation:RouteTableAssociation my-private-subnet-ap-east-1b-rt-association
├─ aws:ec2/routeTableAssociation:RouteTableAssociation my-private-subnet-ap-east-1a-rt-association
├─ aws:ec2/route:Route my-private-subnet-ap-east-1a-nat-gateway-route
├─ aws:ec2/route:Route my-private-subnet-ap-east-1b-nat-gateway-route
└─ pulumi:providers:aws default_5_42_0
Current stack outputs (5):
OUTPUT VALUE
igw [secret]
natGateway nat-0525a2df0549f9d87
privateSubnetIds ["subnet-07c0347881878ea7a","subnet-0859c9586bc678f88"]
publicSubnetIds ["subnet-0bd6c6dd4501e6d6d","subnet-051b8eb71461c53d1"]
vpcId vpc-02c2b3898482aede5
More information at: https://app.pulumi.com/xxxxxx/aws-vpc-ts/dev
Use `pulumi stack select` to change stack; `pulumi stack ls` lists known ones
另一個方法就是透過 pulumi stack output
指令,這個指定就只會列出 stack 的 output 資料。
pulumi stack output
Current stack outputs (5):
OUTPUT VALUE
igw [secret]
natGateway nat-0525a2df0549f9d87
privateSubnetIds ["subnet-07c0347881878ea7a","subnet-0859c9586bc678f88"]
publicSubnetIds ["subnet-0bd6c6dd4501e6d6d","subnet-051b8eb71461c53d1"]
vpcId vpc-02c2b3898482aede5
pulumi stack output
也可以指定要查看的 output 名稱,就可以只輸出該 output 的內容。
$ pulumi stack output vpcId
vpc-02c2b3898482aede5
這個功能就可以很好的與 shell script 搭配,例如透過 AWS CLI 查看 VPC 的內容:
aws ec2 describe-vpcs --vpc-ids "$(pulumi stack output vpcId)"
pulumi stack
與 pulumi stack output
這兩個 CLI 指令都有一個選項 --show-secrets
,可以用來顯示機敏資訊 (secret) 的內容。
$ pulumi stack --show-secrets
... 省略其他輸出 ...
Current stack outputs (5):
OUTPUT VALUE
igw igw-057395905a9300651
... 省略其他輸出 ...
$ pulumi stack output --show-secrets
Current stack outputs (5):
OUTPUT VALUE
igw igw-057395905a9300651
... 省略其他輸出 ...
$ pulumi stack output igw --show-secrets
igw-057395905a9300651